// user business
let errinfo = require('../errinfo');
let responseJsonUtils = require('../utils/responseJsonUtils');
let userUtils = require('../utils/userUtils');
let _ = require('underscore');
let mongoose = require('mongoose');

let ObjectId = mongoose.Types.ObjectId;

let user = module.exports = {};

/**
 * param userId
 */
user.param = function (req, res, next, userId) {
    User.findOne({
        _id: new ObjectId(userId)
    }).exec(function (err, userResult) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        req.user = userResult;
        next();
    });
};

/**
 * check user exist
 */
user.checkExist = function (req, res, next) {
    if (!req.user) {
        // user not exist
        next(responseJsonUtils.json(errinfo.userNotExist, 404));
        return;
    }
    next();
};

/**
 * check delete
 */
user.checkDelete = function (req, res, next) {
    if (req.user.isDelete) {
        // user not exist
        next(responseJsonUtils.json(errinfo.userIsDeleted, 404));
        return;
    }
    next();
};


/**
 * check authorization
 */
user.checkAuthorization = function (req, res, next) {

    let user = req.session.user;

    if (_.indexOf(user.authorities, 'admin') == -1) {
        // no authorization
        next(responseJsonUtils.json(errinfo.userNoAuthorization, 401));
        return;
    }

    next();
};

/**
 * add user
 */
// check input
user.addCheckInput = function (req, res, next) {
    let body = req.body;
    let cellphone = body.cellphone;
    let password = body.password;

    if (typeof(cellphone) === 'undefined') {
        next(responseJsonUtils.json(errinfo.userCellphoneEmpty, 403));
        return;
    }
    if (typeof(password) === 'undefined') {
        next(responseJsonUtils.json(errinfo.userPasswordEmpty, 403));
        return;
    }
    next();
};

// check cellphone
user.addCheckCellphone = function (req, res, next) {

    let body = req.body;

    User.findOne({
        cellphone: body.cellphone,
        kind: userUtils.kind.admin
    }).exec(function (err, user) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        if (user) {
            // cellphone exist
            next(responseJsonUtils.json(errinfo.userCellphoneExist, 403));
            return;
        }
        next();
    });
};

// check nickname
user.addCheckNickname = function (req, res, next) {
    let body = req.body;

    if (typeof(body.nickname) === 'undefined') {
        next();
        return;
    }
    User.findOne({
        nickname: body.nickname,
        kind: userUtils.kind.admin
    }).exec(function (err, user) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        if (user) {
            // nickname exist
            next(responseJsonUtils.json(errinfo.userNicknameExist, 403));
            return;
        }
        next();
    });
};

// check email
user.addCheckEmail = function (req, res, next) {
    let body = req.body;

    if (typeof(body.email) === 'undefined') {
        next();
        return;
    }

    User.findOne({
        email: body.email,
        kind: userUtils.kind.admin
    }).exec(function (err, user) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        if (user) {
            // email exist
            next(responseJsonUtils.json(errinfo.userEmailExist, 403));
            return;
        }
        next();
    });
};

// add suc
user.addSuc = function (req, res, next) {
    let body = req.body;
    // admin user
    Object.assign(body, {
        kind: userUtils.kind.admin
    });

    User.create(body, function (err, userResult) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        res.status(200).json(userResult.toJSON());
    });
};

/**
 * delete user
 */
user.deleteSuc = function (req, res, next) {

    req.user.update({
        isDelete: true,
        deleteTime: new Date(),
        deleteUser: req.session.user
    }, function (err, userResult) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        // redirect to all user
        // res.redirect('/user');
        res.status(200).json(req.user.toJSON());
    });
};


/**
 * update user
 */

// check nickname
user.updateCheckNicknameDuplicate = function (req, res, next) {

    if (typeof(req.body.nickname) === 'undefined') {
        next();
        return;
    }

    let newNickname = req.body.nickname;
    let originalNickname = req.user.nickname;

    if (newNickname === originalNickname) {
        // nickname is the same, do not check.
        next();
        return;
    }

    User.findOne({
        nickname: newNickname,
        kind: userUtils.kind.admin
    }).exec(function (err, user) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        if (user) {
            // nickname exist
            next(responseJsonUtils.json(errinfo.userNicknameDuplicate, 409));
            return;
        }
        next();
    });
};

// check email
user.updateCheckEmailDuplicate = function (req, res, next) {

    if (typeof(req.body.email) === 'undefined') {
        next();
        return;
    }
    let newEmail = req.body.email;
    let originalEmail = req.user.email;

    if (newEmail == originalEmail) {
        // email is the same, do not check.
        next();
        return;
    }

    User.findOne({
        email: newEmail,
        kind: userUtils.kind.admin
    }).exec(function (err, user) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        if (user) {
            // email exist
            next(responseJsonUtils.json(errinfo.userEmailDuplicate, 409));
            return;
        }
        next();
    });
};

// update suc
user.updateSuc = function (req, res, next) {

    _.extend(req.body, {
        updateTime: new Date(),
        updateUser: req.session.user
    });

    req.user.update(req.body, function (err, userResult) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err, err));
            return;
        }
        // logger.debug(userResult);
        // redirect to all user
        // res.redirect('/user/list');
        res.status(200).json(req.user.toJSON());
    });
};

/**
 * get one user
 */
user.getSuc = function (req, res, next) {
    if (req.user) {
        res.status(200).json(req.user.toJSON());
    } else {
        res.status(200).end();
    }
};

/**
 * user list
 */
user.list = function (req, res, next) {

    Object.assign(req.query, {
        kind: userUtils.kind.admin
    });

    User.find(req.query).exec(function (err, userResults) {
        if (err) {
            next(responseJsonUtils.json(errinfo.mongodb.internalError, err));
            return;
        }
        let data = [];
        for (let i in userResults) {
            data.push(userResults[i].toJSON());
        }
        // res.render('/user/list', userResults);
        res.status(200).json(data);
    });
};